package javaNIO1.customerCharset;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;

/**
 * Created with Intel IDEA.
 * 自定义字符集
 *
 * @Auther: gjt
 * @Date: 2024/8/4 14:17
 */
public class Rot13Charset extends Charset {
    private static final String BASE_CHARSET_NAME = "UTF-8";

    Charset baseCharset;

    protected Rot13Charset(String charsetName, String[] aliases) {
        super(charsetName, aliases);

        baseCharset = Charset.forName(BASE_CHARSET_NAME);
    }

    public CharsetEncoder newEncoder() {
        return new Rot13Encoder(this, baseCharset.newEncoder());
    }

    public CharsetDecoder newDecoder() {
        return new Rot13Decoder(this, baseCharset.newDecoder());
    }

    public boolean contains(Charset charset) {
        return false;
    }

    private void rot13(CharBuffer cb) {
        for (int pos = 0; pos < cb.limit(); pos++) {
            char c = cb.get(pos);
            char a = '\u0000'; // 表示空字符
            if ((c >= 'a') && (c <= 'z')) {
                a = 'a';
            }
            if ((c >= 'A') && (c <= 'Z')) {
                a = 'A';
            }

            if (a != '\u0000') {
                c = (char) ((((c - a) + 13) % 26) + a);
                cb.put(c);
            }
        }
    }

    private class Rot13Encoder extends CharsetEncoder {
        private CharsetEncoder baseEncoder;

        Rot13Encoder(Charset charset, CharsetEncoder baseEncoder) {
            super(charset, baseEncoder.averageBytesPerChar(), baseEncoder.maxBytesPerChar());
            this.baseEncoder = baseEncoder;
        }
        protected CoderResult encodeLoop(CharBuffer cb, ByteBuffer bb) {
            CharBuffer tmpcc = CharBuffer.allocate(cb.remaining());
            while(cb.hasRemaining()){
                tmpcc.put(cb.get());
            }
            tmpcc.rewind();

            rot13(tmpcc);
            baseEncoder.reset();

            CoderResult encode = baseEncoder.encode(tmpcc, bb, true);

            cb.position(cb.position() - tmpcc.remaining());
            return encode;
        }
    }

    private class Rot13Decoder extends CharsetDecoder {
        private CharsetDecoder baseDecoder;

        Rot13Decoder (Charset cs, CharsetDecoder baseDecoder){
            super(cs,baseDecoder.averageCharsPerByte(), baseDecoder.maxCharsPerByte());
            this.baseDecoder = baseDecoder;
        }

        protected CoderResult decodeLoop(ByteBuffer bb, CharBuffer cb){
            baseDecoder.reset();
            CoderResult result = baseDecoder.decode(bb, cb, true);
            rot13(cb);
            return result;
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader reader = null;
        if(args.length > 0){
            reader = new BufferedReader(new FileReader(args[0]));
        }else {
            reader = new BufferedReader(new InputStreamReader(System.in));
        }
//        String charset = "X-ROT13";
        String charset = "UTF-8";
        PrintStream printStream = new PrintStream(System.out, false, charset);
        String s = null ;
        while((s = reader.readLine()) != null){
            printStream.println(s);
        }

        printStream.flush();
    }

}
